import { defineConfig, loadEnv } from 'vite';
import path, { resolve } from 'path';

// vue
import vue from '@vitejs/plugin-vue';

// Vite支持JSX
import vueJsx from '@vitejs/plugin-vue-jsx';

// mock
import { viteMockServe } from 'vite-plugin-mock';

// html内容调整 插件
import { createHtmlPlugin } from 'vite-plugin-html';

// 压缩插件
import viteCompression from 'vite-plugin-compression';

// 图片压缩
import viteImagemin from 'vite-plugin-imagemin';

// ui自动导入插件
import Components from 'unplugin-vue-components/vite';
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers';

// setup name 增强
import VueSetupExtend from 'vite-plugin-vue-setup-extend';

// 自动导入composition api
import AutoImport from 'unplugin-auto-import/vite';
import { autoImportList, lodashList } from './src/utils/autoImport';

// 将css转换成兼容多种浏览器的样式
import postcssPresetEnv from 'postcss-preset-env';

// 自定义svg图标
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons';

// esbuild
import eslintPlugin from 'vite-plugin-eslint';

// 编辑器
import monacoEditorPlugin from 'vite-plugin-monaco-editor';

// https://vitejs.dev/config/
export default ({ command, mode }) => {
	// 环境变量
	const env = loadEnv(mode, process.cwd());
	// 生产环境判断
	const isEnvProduction = mode === 'production';
	// vite插件
	const plugins = [
		vue(),
		vueJsx(),
		// 配置vite在运行的时候自动检测eslint规范
		// eslintPlugin({
		// 	include: ['src/**/*.ts', 'src/**/*.js', 'src/**/*.vue', 'src/*.ts', 'src/*.js', 'src/*.vue']
		// }),
		viteMockServe({
			mockPath: 'mock', //mock文件地址
			localEnabled: false, // 开发开关
			prodEnabled: false, // 生产开关
			watchFiles: true, //设置是否监视mockPath对应的文件夹内文件中的更改
			// 地址，相对于 src/main.js 目录
			injectCode: `
				import { setupProdMockServer } from './mockProdServer';
				setupProdMockServer();
			`,
			logger: false, //是否在控制台显示请求日志
			supportTs: false //打开后，可以读取 ts 文件模块。 请注意，打开后将无法监视.js 文件
		}),
		VueSetupExtend(),
		/**
		 *  注入变量到html模板中
		 *  则在 html模板中可以这样获取  <%- TITLE %> <%- injectConfigScript %>
		 *  文档：  https://github.com/anncwb/vite-plugin-html
		 */
		createHtmlPlugin({
			inject: {
				data: {
					TITLE: '千山智矿',
					// 全局动态打包调整数据文件
					injectConfigScript: `<script src="/config.js?v=${new Date().getTime()}"></script>`,
					...env
				}
			},
			minify: true
		}),
		/**
		 * ui按需加载(自动导入)自动导入Vite的按需组件
		 */
		Components({
			resolvers: [ElementPlusResolver()],
			dts: '.components.d.ts'
		}),
		AutoImport({
			// 自动导入vue和vue-router相关函数
			imports: [
				'vue',
				'vue-router',
				{
					// 使用的时候才会自动导入，检查js代码
					'@/utils/autoImport': autoImportList,
					'@/utils/mixin': ['addDateRange', 'dialogMixin', 'pageMixin', 'listMixin', 'treeMixin', 'spreadPage'],
					lodash: lodashList
				}
			],
			eslintrc: {
				enabled: true
			},
			resolvers: [ElementPlusResolver()],
			dts: '.auto-import.d.ts' // 生成 `auto-import.d.ts` 全局声明
		}),
		createSvgIconsPlugin({
			// 指定要缓存的图标文件夹
			iconDirs: [resolve(process.cwd(), 'src/assets/svg')],
			// 执行icon name的格式
			symbolId: 'icon-[name]'
		}),
		monacoEditorPlugin({
			languageWorkers: ['editorWorkerService', 'typescript', 'json', 'html']
		})
		// viteImagemin({
		// 	// 无损压缩配置，无损压缩下图片质量不会变差
		// 	optipng: {
		// 		optimizationLevel: 7
		// 	},
		// 	// 有损压缩配置，有损压缩下图片质量可能会变差
		// 	pngquant: {
		// 		quality: [0.8, 0.9]
		// 	},
		// 	// svg 优化
		// 	svgo: {
		// 		plugins: [
		// 			{
		// 				name: 'removeViewBox'
		// 			},
		// 			{
		// 				name: 'removeEmptyAttrs',
		// 				active: false
		// 			}
		// 		]
		// 	}
		// })
	];
	if (isEnvProduction) {
		plugins.push(
			// gzip插件，打包压缩代码成gzip  文档： https://github.com/anncwb/vite-plugin-compression
			viteCompression()
		);
	}
	// monaco-editor 路径
	const prefix = `monaco-editor/esm/vs`;
	return defineConfig({
		// 基础路径，配合vue-router的createWebHashHistory使用
		base: isEnvProduction ? '/' : './',
		css: {
			preprocessorOptions: {
				scss: {
					charset: false,
					javascriptEnabled: true,
					additionalData: `@import "src/style/index.scss";`
				}
			},
			postcss: {
				plugins: [postcssPresetEnv()]
			}
		},
		// 强制预构建插件包
		optimizeDeps: {
			include: [
				`${prefix}/language/json/json.worker`,
				`${prefix}/language/html/html.worker`,
				`${prefix}/language/typescript/ts.worker`,
				`${prefix}/editor/editor.worker`
			]
		},
		plugins,
		// 删除console,debugger
		minify: 'terser',
		terserOptions: {
			compress: {
				drop_console: true,
				drop_debugger: true
			}
		},
		// 打包环境
		build: {
			outDir: 'dist',
			assetsInlineLimit: 1024,
			cssCodeSplit: true,
			chunkSizeWarningLimit: 1000,
			// 关闭打包计算
			brotliSize: false,
			rollupOptions: {
				output: {
					// 引入文件名的名称
					chunkFileNames: 'static/js/[name]-[hash].js',
					// 包的入口文件名称
					entryFileNames: 'static/js/[name]-[hash].js',
					// 资源文件像 字体，图片等
					assetFileNames: (chunkInfo) => {
						if (['.png', '.jpg', '.jpeg'].includes(path.extname(chunkInfo.name))) {
							return `static/[ext]/[name].[ext]`;
						}
						return `static/[ext]/[name]-[hash].[ext]`;
					},
					// 手动分片
					manualChunks: {
						jsonWorker: [`${prefix}/language/json/json.worker`],
						htmlWorker: [`${prefix}/language/html/html.worker`],
						tsWorker: [`${prefix}/language/typescript/ts.worker`],
						editorWorker: [`${prefix}/editor/editor.worker`]
					}
				}
			}
		},
		server: {
			host: '0.0.0.0',
			port: 5100,
			open: true,
			proxy: {
				// 设置代理
				[env.VITE_APP_BASE_API]: {
					target: env.VITE_APP_TARGET,
					changeOrigin: true,
					rewrite: (path) => path.replace(env.VITE_APP_BASE_API, env.VITE_APP_TI)
				}
			}
		},
		// alias 现在会被传递给 @rollup/plugin-alias 并不再需要开始/结尾处的斜线了。
		// 此行为目前是一个直接替换，所以 1.0 风格的目录别名需要删除其结尾处的斜线：
		resolve: {
			// 导入时省略扩展名
			extensions: ['.js', '.ts', '.jsx', '.tsx', '.json', '.vue'],
			alias: {
				// 如果报错__dirname找不到，需要安装node,执行yarn add @types/node --save-dev
				'@': resolve(__dirname, 'src'),
				'@a': resolve(__dirname, 'src/api'),
				'@c': resolve(__dirname, 'src/components'),
				'@s': resolve(__dirname, 'src/store'),
				'@u': resolve(__dirname, 'src/utils')
			}
		}
	});
};
